//
//  EAGLView.m
//  StmartBS
//
//  Created by Sangwon Lee on 10. 9. 10..
//  Copyright __MyCompanyName__ 2010. All rights reserved.
//

#import  "EAGLView.h"
#include "3DEDefine.h"
#include "Interfaces.h"



#define GL_RENDERBUFFER 0x8d41

@implementation EAGLView

@synthesize animating;
@dynamic animationFrameInterval;

/// 멀티 터치에서 카메라 컨트롤에 쓰임
//  puos 20100917
float len;
float view_distance;
float prev_view_distance;


#define BINIT   0 
#define BSCALE  1
#define BROTATE 2

int bFlagVar = BINIT;


// You must implement this method
+ (Class)layerClass
{
    return [CAEAGLLayer class];
}

//The EAGL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
- (id)initWithCoder:(NSCoder*)coder
{    
    if ((self = [super initWithCoder:coder]))
	{
        // Get the layer
        CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;

        eaglLayer.opaque = TRUE;
        eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                        [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];

		
		EAGLRenderingAPI api = kEAGLRenderingAPIOpenGLES1;
		m_context = [[EAGLContext alloc] initWithAPI:api];
		 
		if (!m_context || ![EAGLContext setCurrentContext:m_context]) 
		{
		 [self release];
		 return nil;
		}
							
        NSLog(@"Using OpenGL ES 1.1");
        m_pRenderingEngine = ES1::CreateRenderingEngine();        
        m_pEngine          = Create3DEngine(m_pRenderingEngine);

		
		//  
		[m_context
		 renderbufferStorage:GL_RENDERBUFFER
		 fromDrawable: eaglLayer];
		
		
		NSString* bundlePath =[[NSBundle mainBundle] resourcePath];
		std::string _path = [bundlePath UTF8String];
		
        int width  = self.bounds.size.width;
        int height = self.bounds.size.height;
        m_pEngine->Initialize(width, height);
		
		_path += "/";
		
		//  리소스 경로를 설정한다
		m_pEngine->SetRscPath(_path.c_str());
		
		//pSceneNode = NULL;
		m_pEngine->DestroyScene();
		m_pEngine->CreateScene("one.scene");
		vec3 vDir = vec3(0,-0.4,1);
		m_pEngine->NodeFitCamera("root",vDir, 15);
		
        [self drawView: nil];
        m_timestamp = CACurrentMediaTime();
        
        CADisplayLink* _displayLink;
        _displayLink = [CADisplayLink displayLinkWithTarget:self
												  selector:@selector(drawView:)];
        
        [_displayLink addToRunLoop:[NSRunLoop currentRunLoop]
						  forMode:NSDefaultRunLoopMode];
		
        displayLink = nil;
        animating = FALSE;
        displayLinkSupported = FALSE;
        animationFrameInterval = 1;
        animationTimer = nil;

        // A system version of 3.1 or greater is required to use CADisplayLink. The NSTimer
        // class is used as fallback when it isn't available.
        NSString *reqSysVer = @"3.1";
        NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
        if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)
            displayLinkSupported = TRUE;
   
	}

    return self;
}


- (void) drawView: (CADisplayLink*) _displayLink
{
	    if (_displayLink != nil) 
	{
        float elapsedSeconds = _displayLink.timestamp - m_timestamp;
        m_timestamp = _displayLink.timestamp;
    
		if(m_pEngine)
		{  m_pEngine->UpdateAnimation(elapsedSeconds);
		} 	
	}
    
	 
	if(m_pEngine)
	{ m_pEngine->Render();
	}
	
	// 버퍼 present
	[m_context presentRenderbuffer:GL_RENDERBUFFER];
}


- (void)layoutSubviews
{
	
}

- (NSInteger)animationFrameInterval
{
    return animationFrameInterval;
}

- (void)setAnimationFrameInterval:(NSInteger)frameInterval
{
    // Frame interval defines how many display frames must pass between each time the
    // display link fires. The display link will only fire 30 times a second when the
    // frame internal is two on a display that refreshes 60 times a second. The default
    // frame interval setting of one will fire 60 times a second when the display refreshes
    // at 60 times a second. A frame interval setting of less than one results in undefined
    // behavior.
    if (frameInterval >= 1)
    {
        animationFrameInterval = frameInterval;

        if (animating)
        {
            [self stopAnimation];
            [self startAnimation];
        }
    }
}

- (void)startAnimation
{
    if (!animating)
    {
        if (displayLinkSupported)
        {
            // CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed
            // if the system version runtime check for CADisplayLink exists in -initWithCoder:. The runtime check ensures this code will
            // not be called in system versions earlier than 3.1.

            displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(drawView:)];
            [displayLink setFrameInterval:animationFrameInterval];
            [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        }
        else
            animationTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)((1.0 / 60.0) * animationFrameInterval) target:self selector:@selector(drawView:) userInfo:nil repeats:TRUE];

        animating = TRUE;
    }
}

- (void)stopAnimation
{
    if (animating)
    {
        if (displayLinkSupported)
        {
            [displayLink invalidate];
            displayLink = nil;
        }
        else
        {
            [animationTimer invalidate];
            animationTimer = nil;
        }

        animating = FALSE;
    }
}

/* - (void)viewDidLoad
{
	EAGLView.transform = CGAffineTransformInvert(EAGLView.superview.transform);
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
	return YES;
}

- (void)didReceiveMemoryWarning{
	[super didReceiveMemoryWarning];
}
*/


/* - (void)sendSubviewToBack:(UIView *) BackGroundView
{
	CGRect frame = [[UIScreen mainScreen]applicationFrame];
	UIView *BackGroundView = [[[UIView alloc]initWithFrame:frame]autorelease];
	BackGroundView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"bg.png"]];
	
	self.EAGLView = [[[UITableView alloc] initWithFrame:frame style:UItableViewStyleGrouped]autorelease]; 
	self.EAGLView.backgroundView = BackGroundView;
}
*/



 
	


- (void)dealloc
{
    SAFE_DELETE(m_pEngine);
	[super dealloc];
}

float _ratio = 100;
int   nCount  = 0;

// 터치 입력 처리
- (void) touchesMoved:(NSSet*) touches withEvent:(UIEvent*)event
{
	NSArray *allTouches = [touches allObjects];
	int count = [allTouches count];
	
		
	if (count == 1) {
		CGPoint p1 = [[allTouches objectAtIndex:0] locationInView:self];
		
		//float tmpLen = sqrt( ((int)p1.x-(int)pt.x)*((int)p1.x-(int)pt.x) + ((int)p1.y-(int)pt.y)*((int)p1.y-(int)pt.y));
		
		if(nCount <= 1)
		{
			if(m_pEngine)
			{	m_pEngine->HandleMessages(0,9,p1.x,p1.y); // 회전
			}
			
			//if(m_pEngine)
			//{  m_pEngine->HandleMessages( 0, 1, p1.x, p1.y );
			//}
		} 	
	    // 터치 이동시 윈도우 포지션		
		//if(m_pEngine)
		//{  m_pEngine->HandleMessages( 0, 1, p1.x, p1.y );
		//}  	
				
		NSLog(@"touch Point Moved X=%d, Y=%d\n", (int)p1.x, (int)p1.y);
		
	} else if (count >1) {
		CGPoint p1 = [[allTouches objectAtIndex:0] locationInView:self];
		CGPoint p2 = [[allTouches objectAtIndex:1] locationInView:self];
		
		//bFlagVar = BROTATE;
		
		float tmpLen = sqrt( ((int)p1.x-(int)p2.x)*((int)p1.x-(int)p2.x) + ((int)p1.y-(int)p2.y)*((int)p1.y-(int)p2.y));
		
	    view_distance = (tmpLen - len);

		//  지금 계산했던 거리값을 비교값으로 저장 
	    len = tmpLen;
		
		bFlagVar = BSCALE;
		
	
		switch (bFlagVar) 
		{
			case BSCALE:
			    { 
					// 거리가 좁고 length 가 일정할때 
					if((len < _ratio) && (fabs(view_distance) <= 0.0f ))
				    { bFlagVar = BROTATE;
					}
				}
				break;
				
			case BROTATE:
			    {
					// 거리가 넓어지고 length 가 일정치 않을때
					if(len > _ratio && (fabs(view_distance) > 0.1f ))
					{ bFlagVar = BSCALE;
					} 	
			    }
				break;
				
			default:
				break;
		}
		
		/*
		if(bFlagVar == BROTATE)
		{
			if(m_pEngine)
			{	m_pEngine->HandleMessages(0,9,p1.x,p1.y); // 회전
			}
			
		}
		/**/ 
		//else if(bFlagVar == BSCALE)
		{
			// 1 은  + 2는 -
			int nSign = (view_distance > 0) ? 2 : 1;  
			
			UINT wParam = 0;
			UINT lParam = 0;
			
			wParam =                nSign;
			lParam = MAKEDWORD((int)(p1.x),((int)p1.y));
			
			//int a1 = LOWORD(lParam);
			//int b1 = HIWORD(lParam);
						
			//  현재거리와 이전거리의 차를 넣는다 . 안에서 +/- 값으로 줌 인/아웃을 변경
			if(m_pEngine)
			{ m_pEngine->HandleMessages( 0, 8, wParam , lParam );
			}  
			
		} 	
		
	    NSLog(@"view_distance=%.15f", (double)view_distance);
	}
}

IMSceneNode* pSceneNode = NULL;

- (void) touchesBegan:(NSSet*) touches withEvent:(UIEvent*)event 
{
	NSArray *allTouches = [touches allObjects];
	int count = [allTouches count];
	
	if (count == 1) {
		CGPoint p1 = [[allTouches objectAtIndex:0] locationInView:self];
		
		if (nCount <= 0) 
		{
			// 터치 시작시 윈도우 포지션값을 넣는다 
			if(m_pEngine)
			{ m_pEngine->HandleMessages( 0, 0, p1.x , p1.y );
			} 		
		}
		
		
		// 선충돌 테스트 
		{
		
		  if(pSceneNode)
		  {   vec4 temp = vec4(1.0f,1.0f,1.0f,1.0f);
			  pSceneNode->SetGroupVertexColor(temp);
		  }
			
		  char filterList[500];
			
			sprintf(filterList,"seochokt_3f_wall;seochokt_3f_step;seochokt_3f_pill;seochokt_3f_furn;seochokt_3f_elev;seochokt_3f_door;seochokt_3f_curt;seochokt_3f_bott;seochokt_3f_bath");	
		//	strcat("seochokt_3f_wall", filterList);
//			strcat("seochokt_3f_step", filterList);
//			strcat("seochokt_3f_pill", filterList);
//			strcat("seochokt_3f_furn", filterList);
//			strcat("seochokt_3f_elev", filterList);
//			strcat("seochokt_3f_door", filterList);
//			strcat("seochokt_3f_curt", filterList);
//			strcat("seochokt_3f_bott", filterList);
//			strcat("seochokt_3f_bath", filterList);
			
			
		  pSceneNode = m_pEngine->RayIntersectNode(p1.x,p1.y,filterList); 
		
		  if(pSceneNode)
		  {   //vec4 temp = vec4(1.0f,0.0f,0.0f,1.0f);
			  //pSceneNode->SetGroupVertexColor(temp);
			  //alert(0);
			  			  
			  if(strcmp(pSceneNode->Get_Name(),"seochokt_3f_light") == 0)
			  {
				  UIAlertView *alert;
				  
				  string str;
				  
				  
				  str = pSceneNode->Get_Name();
				  
				  NSString *stmt = nil;
				  stmt = [NSString stringWithUTF8String:pSceneNode->Get_Name()]	;			  
				  

				  
				 // NSString *stmt = [NSString initWithUTF8String:pSceneNode->Get_Name()];
				  
				  
								  
				  alert = [[UIAlertView alloc]
						   initWithTitle:@"Information"
						   message:stmt 
						   delegate:self 
						   cancelButtonTitle:@"OK" 
						   otherButtonTitles:nil
						   ];
				  [alert show];
				  [alert release];

				  
				  
//				  StatusView.alpha = 0.0;
//				  
//				  [UIView beginAnimations:nil context:NULL];
//				  [UIView setAnimationDuration:1.0];
//				  
//				  StatusView.alpha = 1.0;
//				  
//				  [UIView commitAnimations];
				  
				  
			  }	   
		  }
			
		}	
		
		nCount = nCount  + 1;
		
		//bFlagVar = BROTATE;
	//	NSLog(@"touch Point Began X=%d, Y=%d\n", (int)p1.x, (int)p1.y);
		
	} else if (count >1) {
		CGPoint p1 = [[allTouches objectAtIndex:0] locationInView:self];
		CGPoint p2 = [[allTouches objectAtIndex:1] locationInView:self];
		
//		pt = p1;
		
		/*
		if(m_pEngine)
		{ 
			m_pEngine->HandleMessages(0,0,p1.x,p1.y);
		} 
		 /**/
		
		len = sqrt( ((int)p1.x-(int)p2.x)*((int)p1.x-(int)p2.x) + ((int)p1.y-(int)p2.y)*((int)p1.y-(int)p2.y));
		
		bFlagVar = BSCALE;
		
		/*
		if(len > _ratio)
		{ bFlagVar = BSCALE;
		}
		else 
		{ bFlagVar = BROTATE;
		} 
		 /**/
	}
	
} 


- (void) touchesEnded:(NSSet*) touches withEvent:(UIEvent*)event 
{	bFlagVar = BINIT;
	nCount  = 0;
}

- (BOOL) isMultipleTouchEnabled {
	return YES;
}


// 버튼 액션 처리
- (IBAction)HomeView: (id)sender 
{
	pSceneNode = NULL;
	m_pEngine->DestroyScene();
	m_pEngine->CreateScene("one.scene");
	vec3 vDir = vec3(0.1,-0.2,1);
	m_pEngine->NodeFitCamera("root",vDir,15.0f);
	
}
- (IBAction)FirstFloorView: (id)sender
{
	pSceneNode = NULL;
	m_pEngine->DestroyScene();
	m_pEngine->CreateScene("two.scene");
	vec3 vDir = vec3(0,-1,0);
	m_pEngine->NodeFitCamera("root",vDir,10.0f);
	
}
//- (IBAction)SecondFloorView: (id)sender
//{
//	pSceneNode = NULL;
//	m_pEngine->DestroyScene();
//	m_pEngine->CreateScene("three.scene");	
//	vec3 vDir = vec3(0,-1,0);
//	m_pEngine->NodeFitCamera("root",vDir);
//	
//	/*
//	int width  = self.bounds.size.width;
//	int height = self.bounds.size.height;
//	
//	char filterList[500];
//	
//	sprintf(filterList,"seochokt_3f_wall;seochokt_3f_step;seochokt_3f_pill;seochokt_3f_furn;seochokt_3f_elev;seochokt_3f_door;seochokt_3f_curt;seochokt_3f_bott;seochokt_3f_bath");	
//	
//	
//	
//	pSceneNode = m_pEngine->RayIntersectNode(width * 0.5f,height * 0.5f,filterList); 
//	
//	if(pSceneNode)
//	{   vec4 temp = vec4(1.0f,0.0f,0.0f,1.0f);
//		pSceneNode->SetGroupVertexColor(temp);
//	}
//	/**/
//}


- (IBAction)InfoView: (id)sender
{
	UIAlertView *alert;
	
		alert = [[UIAlertView alloc]
				 initWithTitle:@"Information"
				 message:@"KT 서초 센터\nSmart IBS by KSIC\n http://www.ksic.net" 
				 delegate:self 
				 cancelButtonTitle:@"OK" 
				 otherButtonTitles:nil
				 ];
	[alert show];
	[alert release];
	
}


@end
